package com.language.filter;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.util.StringUtils;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.language.annotation.JsonTranslateFilter;
import com.language.annotation.Translate;
import com.language.service.EhcacheService;

import lombok.extern.slf4j.Slf4j;

/**
 * @author zhangbowen
 * @since 2020-01-17 14:07
 */
@Slf4j
@JsonComponent
public class TranslateJsonFilter extends SimpleBeanPropertyFilter {

    @Autowired
    private EhcacheService ehcacheService;

    public TranslateJsonFilter() {
        super();
    }

    @Override
    protected boolean include(BeanPropertyWriter writer) {
        return super.include(writer);
    }

    @Override
    protected boolean include(PropertyWriter writer) {
        return super.include(writer);
    }

    @Override
    protected boolean includeElement(Object elementValue) {
        return super.includeElement(elementValue);
    }

    @Override
    public void serializeAsElement(Object elementValue, JsonGenerator jgen, SerializerProvider provider,
        PropertyWriter writer) throws Exception {
        super.serializeAsElement(elementValue, jgen, provider, writer);
    }

    @Override
    public void depositSchemaProperty(PropertyWriter writer, JsonObjectFormatVisitor objectVisitor,
        SerializerProvider provider) throws JsonMappingException {
        super.depositSchemaProperty(writer, objectVisitor, provider);
    }

    @Override
    public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer)
        throws Exception {
        // ehcacheService = ehcacheService == null ? SpringUtil.getBean(EhcacheService.class) : ehcacheService;
        if (pojo.getClass().isAnnotationPresent(JsonTranslateFilter.class)) {
            JsonTranslateFilter jsonTranslateFilter = pojo.getClass().getAnnotation(JsonTranslateFilter.class);
            boolean isTranslate = jsonTranslateFilter.value();
            if (isTranslate) {
                doConvert(pojo);
            }
        }

        super.serializeAsField(pojo, jgen, provider, writer);
    }

    private Object doConvert(Object in) {

        Map<String, Integer> refIdMap = new HashMap<>();
        try {
            Field[] fields = in.getClass().getDeclaredFields();
            // for (Field field : fields) {
            // field.setAccessible(true);
            //
            // if (field.isAnnotationPresent(RefId.class) && field.getType().equals(Integer.class)) {
            // Integer refId = (Integer)field.get(in);
            // RefId refAnnotation = field.getAnnotation(RefId.class);
            // String groupId = refAnnotation.groupId();
            // refIdMap.put(groupId, refId);
            // }
            // }
            // 获取refId的分组refType
            for (Field field : fields) {
                field.setAccessible(true);

                if (field.isAnnotationPresent(Translate.class)) {
                    Translate translateAnnotation = field.getAnnotation(Translate.class);
                    String refName = translateAnnotation.refName();
                    if (StringUtils.isEmpty(refName)) {
                        continue;
                    }

                    Field refField = in.getClass().getDeclaredField(refName);
                    refField.setAccessible(true);
                    Integer refId = (Integer)refField.get(in);
                    String groupId = translateAnnotation.groupId();
                    refIdMap.put(groupId, refId);
                }
            }

            for (Field field : fields) {
                field.setAccessible(true);
                if (field.isAnnotationPresent(Translate.class)) {
                    Translate translateAnnotation = field.getAnnotation(Translate.class);
                    String groupId = translateAnnotation.groupId();
                    // refId和被翻译的数据必须属于同一个refType
                    Integer refId = refIdMap.get(groupId);
                    if (refId != null) {
                        // 获取infoType,languageType
                        String[] infoTypeArray = translateAnnotation.infoType();

                        String language = TranslateUtil.languageThreadLocal.get();

                        Map<String, String> translationMap = ehcacheService.getTranslationMap();

                        // 被翻译值的原始值
                        String defaultText = String.valueOf(field.get(in));
                        List<String> translationTextList = new ArrayList<>();
                        // 从翻译map中取出匹配的值
                        for (String infoType : infoTypeArray) {
                            String translationKey = refId + ":" + infoType + ":" + language;
                            String translationValue = translationMap.get(translationKey);
                            if (!StringUtils.isEmpty(translationValue)) {
                                translationTextList.add(translationValue);
                            }
                        }

                        // 复制给翻译的值
                        String translationText = translationTextList.stream().findFirst().orElse(defaultText);

                        // 翻译后重新设置
                        field.set(in, translationText);
                    }
                }
            }
        } catch (Exception e) {
            log.warn("多语言序列化时异常,被翻译的对象:{},message:{}", in, e.toString(), e);
        }
        return in;
    }
}
